/* 
 *
 */
package com.cory.admin.sys.controller.admin;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.cory.admin.sys.domain.excel.SysUserExport;
import com.cory.boot.component.easypoi.EasyExcelUtils;
import com.cory.utils.lang.DateUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cory.admin.sys.controller.AdminController;
import com.cory.admin.sys.domain.entity.SysDept;
import com.cory.admin.sys.domain.entity.SysRole;
import com.cory.admin.sys.domain.entity.SysUser;
import com.cory.admin.sys.service.SysDeptService;
import com.cory.admin.sys.service.SysRoleService;
import com.cory.admin.sys.service.SysUserRoleService;
import com.cory.admin.sys.service.SysUserService;
import com.cory.admin.sys.utils.AdminUtils;
import com.cory.boot.domain.bean.Result;
import com.cory.boot.domain.enumdef.EState;
import com.cory.boot.utils.SysUtils;
import com.cory.module.oplog.core.OpLogClient;
import com.cory.utils.security.CoderUtils;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;

/**
 * 用户管理 
 * @author xiongcong
 * @date 2020-02-04
 */
@Controller
@RequestMapping("admin/sys/user")
public class SysUserController extends AdminController {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysDeptService sysDeptService;
    
    @RequestMapping("index")
    public String index(Model model) {
        return "admin/sys/user/index";
    }
    
    @RequestMapping("list")
    public String list(SysUser param, Model model) {
        param.setTenantId(super.getTenantId());
        param.setUserType(super.getPrincipal().getUserType());
        
        super.startPage();
        List<SysUser> list = sysUserService.list(param);
        
        List<String> deptCodes = list.stream().filter(i -> StringUtils.isNotBlank(i.getDeptCode()))
                .map(i -> i.getDeptCode()).distinct().collect(Collectors.toList());
        List<SysDept> depts = sysDeptService.getByCodes(super.getTenantId(), deptCodes);
        Map<String, String> deptMap = depts.stream().collect(Collectors.toMap(i -> i.getCode(), i -> i.getName()));
        model.addAttribute("deptMap", deptMap);
        
        model.addAttribute("page", new PageInfo<>(list));
        model.addAttribute("param", param);
        return "admin/sys/user/list";
    }

    /**
     * 导出Excel表格
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "/exportExcel")
    public void exportExcel(SysUser param, HttpServletResponse response){
        param.setTenantId(super.getTenantId());
        param.setUserType(super.getPrincipal().getUserType());
        List<SysUser> list = sysUserService.list(param);
        List<SysUserExport> exportList = Lists.newArrayList();
        if(CollectionUtils.isNotEmpty(list)) {
            List<String> deptCodes = list.stream().filter(i -> StringUtils.isNotBlank(i.getDeptCode()))
                    .map(i -> i.getDeptCode()).distinct().collect(Collectors.toList());
            List<SysDept> depts = sysDeptService.getByCodes(super.getTenantId(), deptCodes);
            Map<String, String> deptMap = depts.stream().collect(Collectors.toMap(i -> i.getCode(), i -> i.getName()));
            list.forEach(u -> {
                SysUserExport export = new SysUserExport();
                BeanUtils.copyProperties(u,export);
                export.setSuperFlag(u.getSuperFlag() + "");
                export.setDeptName(deptMap.get(u.getDeptCode()));

                List<SysRole> roleList = sysRoleService.selectRoleListByUserId(u.getId());
                if(CollectionUtils.isNotEmpty(roleList)) {
                    List<String> roleNameList = roleList.stream().map(i -> i.getName()).collect(Collectors.toList());
                    export.setRoleName(String.join(",",roleNameList));
                }

                exportList.add(export);
            });
        }

        EasyExcelUtils.exportExcel(exportList,SysUserExport.class,"系统管理表-" + DateUtils.getDate(),null,response);
    }
    
    @RequestMapping("form")
    public String form(Integer id, Model model) {
        if (id != null) {
            SysUser info = sysUserService.getById(id);
            model.addAttribute("info", info);
            if (StringUtils.isNotBlank(info.getDeptCode()) && !"0".equals(info.getDeptCode())) {
                model.addAttribute("deptName", sysDeptService.getByCode(info.getTenantId(), info.getDeptCode()).getName());
            } else {
                model.addAttribute("deptName", SysUtils.getEntName());
            }
        }
        return "admin/sys/user/form";
    }
    
    @RequestMapping("save")
    @ResponseBody
    public Result<?> save(SysUser info) {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.ne("state", EState.DELETE.key).eq("login_name", info.getLoginName());
        
        SysUser tmp = sysUserService.getOne(wrapper);
        if (tmp != null && (info.getId() == null || !info.getId().equals(tmp.getId()))) {
            return Result.fail("登录名称已存在");
        }
        
        if (info.getId() == null) {
            info.setPassword(CoderUtils.md5(info.getPassword()));
            info.setTenantId(super.getTenantId());
            info.setUserType(super.getPrincipal().getUserType());
            sysUserService.save2Log(info);
        } else {
            sysUserService.updateById2Log(info);
        }
        
        return Result.success("保存成功");
    }
    
    @RequestMapping("delete")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Result<?> delete(Integer id, String ids) {
        List<Integer> idList = id != null ? Lists.newArrayList(id) : 
            Arrays.asList(ids.split(",")).stream().filter(item -> StringUtils.isNotBlank(item))
            .map(item -> Integer.valueOf(item)).collect(Collectors.toList());
        
        if (idList.size() > 0) {
            for (Integer i : idList) {
                sysUserService.delete(i);
            }
        }
        
        return Result.success((idList.size() > 1 ? "批量" : "") + "删除成功");
    }
    
    @RequestMapping("updateState")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Result<?> updateState(Integer id, String ids, Integer state) {
        List<Integer> idList = id != null ? Lists.newArrayList(id) : 
            Arrays.asList(ids.split(",")).stream().filter(item -> StringUtils.isNotBlank(item))
            .map(item -> Integer.valueOf(item)).collect(Collectors.toList());
        
        if (idList.size() > 0) {
            sysUserService.updateStateByIds2Log(idList, state);
        }
        
        return Result.success((idList.size() > 1 ? "批量" : "") + (state == 1 ? "启用" : "禁用") + "成功");
    }
    
    @GetMapping("password")
    public String password(Integer id, Model model) {
        model.addAttribute("info", sysUserService.getById(id));
        return "admin/sys/user/password";
    }
    
    @PostMapping("password")
    @ResponseBody
    public Result<?> update(HttpSession session, Integer id, String password) {
        assertNotNull(password);
        
        SysUser update = new SysUser();
        update.setId(id);
        update.setPassword(CoderUtils.md5(password));
        sysUserService.updateById(update);
        OpLogClient.addLog(SysUser.class, id, "重置密码");
        return Result.success("修改成功");
    }
    
    @GetMapping("role")
    public String role(Integer id, Model model) {
        SysUser info = sysUserService.getById(id);
        model.addAttribute("info", info);
        model.addAttribute("userRoleIds", sysUserRoleService.selectUserRoleIds(id));
        
        SysRole param = new SysRole();
        param.setTenantId(super.getTenantId());
        param.setUserType(info.getUserType());
        model.addAttribute("roles", sysRoleService.list(param));
        return "admin/sys/user/role";
    }
    
    @PostMapping("saveRole")
    @ResponseBody
    public Result<?> saveRole(HttpSession session, Integer id, String roleIds) {
        assertNotNull(id);
        roleIds = StringUtils.defaultIfBlank(roleIds, "");
        List<Integer> roleIdList = Stream.of(roleIds.split(",")).filter(i -> StringUtils.isNotBlank(i))
                .map(i -> Integer.valueOf(i)).collect(Collectors.toList());
        
        sysUserRoleService.saveUserRoles(id, roleIdList);
        OpLogClient.addLog(SysUser.class, id, "分配角色");
        return Result.success("保存成功");
    }
    
    @RequestMapping("select")
    public String select(Model model, Integer selectType, String fn,  String selectedUserIds) {
        model.addAttribute("selectType", selectType);
        model.addAttribute("fn", fn);
        
        if (StringUtils.isNotBlank(selectedUserIds)) {
            List<Integer> idList = Arrays.asList(selectedUserIds.split(",")).stream().filter(item -> StringUtils.isNotBlank(item))
                .map(item -> Integer.valueOf(item)).collect(Collectors.toList());
            
            model.addAttribute("selectedUsers", AdminUtils.listSysUserByIds(idList));
        }
        model.addAttribute("selectedUserIds", selectedUserIds);
        return "admin/sys/user/select";
    }
    
    @RequestMapping("selectList")
    public String selectList(SysUser param, Model model) {
        param.setTenantId(super.getTenantId());
        param.setUserType(super.getPrincipal().getUserType());
        
        List<SysUser> list = sysUserService.list(param);
        
        model.addAttribute("list", list);
        model.addAttribute("param", param);
        return "admin/sys/user/select.list";
    }
    
    @RequestMapping("selectBatchList")
    public String selectBatchList(SysUser param, Model model) {
        param.setTenantId(super.getTenantId());
        param.setUserType(super.getPrincipal().getUserType());
        
        List<SysUser> list = sysUserService.list(param);
        
        model.addAttribute("list", list);
        model.addAttribute("param", param);
        return "admin/sys/user/select.batch.list";
    }
}
